{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Noise Removal Autoencoder\n",
    "\n",
    "__Autoencoder__ help us dealing with noisy data. Since the __latent space__ only keeps the important information, the noise will not be preserved in the space and we can reconstruct the cleaned data.\n",
    "\n",
    "We will implement an autoencoder that takes a noisy image as input and tries to reconstruct the image without noise. In this way, the hidden nodes try to be expert in detecting the crusial patterns and ignore the noise pattern."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports:\n",
    "We will start with importing the needed libraries for our code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Input data:\n",
    "For this tutorial we use the MNIST dataset. MNIST is a dataset of handwritten digits. If you are into machine learning, you might have heard of this dataset by now. MNIST is kind of benchmark of datasets for deep learning. One other reason that we use the MNIST is that it is easily accesible through Tensorflow. If you want to know more about the MNIST dataset you can check Yann Lecun's website.\n",
    "We can easily import the dataset and see the size of training, test and validation set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting MNIST_data/train-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data/train-labels-idx1-ubyte.gz\n",
      "Extracting MNIST_data/t10k-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data/t10k-labels-idx1-ubyte.gz\n",
      "Size of:\n",
      "- Training-set:\t\t55000\n",
      "- Test-set:\t\t10000\n",
      "- Validation-set:\t5000\n"
     ]
    }
   ],
   "source": [
    "# Import MNIST data\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "mnist = input_data.read_data_sets(\"MNIST_data/\", one_hot=True)\n",
    "\n",
    "print(\"Size of:\")\n",
    "print(\"- Training-set:\\t\\t{}\".format(len(mnist.train.labels)))\n",
    "print(\"- Test-set:\\t\\t{}\".format(len(mnist.test.labels)))\n",
    "print(\"- Validation-set:\\t{}\".format(len(mnist.validation.labels)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hyper-parameters:\n",
    "Hyper-parameters are important parameters which are not learned by the network. So, we have to specify them externally. These parameters are constant and they are not learnable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# hyper-parameters\n",
    "logs_path = \"./logs/noiseRemoval\"  # path to the folder that we want to save the logs for Tensorboard\n",
    "learning_rate = 0.001  # The optimization learning rate\n",
    "epochs = 10  # Total number of training epochs\n",
    "batch_size = 100  # Training batch size\n",
    "display_freq = 100  # Frequency of displaying the training results\n",
    "\n",
    "# Network Parameters\n",
    "# We know that MNIST images are 28 pixels in each dimension.\n",
    "img_h = img_w = 28\n",
    "\n",
    "# Images are stored in one-dimensional arrays of this length.\n",
    "img_size_flat = img_h * img_w\n",
    "\n",
    "# number of units in the hidden layer\n",
    "h1 = 100\n",
    "\n",
    "# level of the noise in noisy data\n",
    "noise_level = 0.6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Graph:\n",
    "Like before, we start by constructing the graph. But, we need to define some functions that we need rapidly in our code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# weight and bais wrappers\n",
    "def weight_variable(name, shape):\n",
    "    \"\"\"\n",
    "    Create a weight variable with appropriate initialization\n",
    "    :param name: weight name\n",
    "    :param shape: weight shape\n",
    "    :return: initialized weight variable\n",
    "    \"\"\"\n",
    "    initer = tf.truncated_normal_initializer(stddev=0.01)\n",
    "    return tf.get_variable('W_' + name,\n",
    "                           dtype=tf.float32,\n",
    "                           shape=shape,\n",
    "                           initializer=initer)\n",
    "\n",
    "\n",
    "def bias_variable(name, shape):\n",
    "    \"\"\"\n",
    "    Create a bias variable with appropriate initialization\n",
    "    :param name: bias variable name\n",
    "    :param shape: bias variable shape\n",
    "    :return: initialized bias variable\n",
    "    \"\"\"\n",
    "    initial = tf.constant(0., shape=shape, dtype=tf.float32)\n",
    "    return tf.get_variable('b_' + name,\n",
    "                           dtype=tf.float32,\n",
    "                           initializer=initial)\n",
    "\n",
    "\n",
    "def fc_layer(x, num_units, name, use_relu=True):\n",
    "    \"\"\"\n",
    "    Create a fully-connected layer\n",
    "    :param x: input from previous layer\n",
    "    :param num_units: number of hidden units in the fully-connected layer\n",
    "    :param name: layer name\n",
    "    :param use_relu: boolean to add ReLU non-linearity (or not)\n",
    "    :return: The output array\n",
    "    \"\"\"\n",
    "    with tf.variable_scope(name):\n",
    "        in_dim = x.get_shape()[1]\n",
    "        W = weight_variable(name, shape=[in_dim, num_units])\n",
    "        tf.summary.histogram('W', W)\n",
    "        b = bias_variable(name, [num_units])\n",
    "        tf.summary.histogram('b', b)\n",
    "        layer = tf.matmul(x, W)\n",
    "        layer += b\n",
    "        if use_relu:\n",
    "            layer = tf.nn.relu(layer)\n",
    "        return layer\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have our helper functions we can create our graph.\n",
    "\n",
    "We we create an __Autoencoder__ with one hidden layer. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create graph\n",
    "# Placeholders for inputs (x), outputs(y)\n",
    "with tf.variable_scope('Input'):\n",
    "    x_original = tf.placeholder(tf.float32, shape=[None, img_size_flat], name='X_original')\n",
    "    x_noisy = tf.placeholder(tf.float32, shape=[None, img_size_flat], name='X_noisy')\n",
    "\n",
    "\n",
    "fc1 = fc_layer(x_noisy, h1, 'Hidden_layer', use_relu=True)\n",
    "out = fc_layer(fc1, img_size_flat, 'Output_layer', use_relu=False)\n",
    "\n",
    "# Define the loss function, optimizer, and accuracy\n",
    "with tf.variable_scope('Train'):\n",
    "    with tf.variable_scope('Loss'):\n",
    "        loss = tf.reduce_mean(tf.losses.mean_squared_error(x_original, out), name='loss')\n",
    "        tf.summary.scalar('loss', loss)\n",
    "    with tf.variable_scope('Optimizer'):\n",
    "        optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, name='Adam-op').minimize(loss)\n",
    "\n",
    "# Initializing the variables\n",
    "init = tf.global_variables_initializer()\n",
    "\n",
    "# Add 5 images from original, noisy and reconstructed samples to summaries\n",
    "tf.summary.image('original', tf.reshape(x_original, (-1, img_w, img_h, 1)), max_outputs=5)\n",
    "tf.summary.image('noisy', tf.reshape(x_noisy, (-1, img_w, img_h, 1)), max_outputs=5)\n",
    "tf.summary.image('reconstructed', tf.reshape(out, (-1, img_w, img_h, 1)), max_outputs=5)\n",
    "\n",
    "# Merge all the summaries\n",
    "merged = tf.summary.merge_all()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train:\n",
    "As soon as the graph is created, we can run it on a session.\n",
    "\n",
    "A ```tf.Session()``` is as good as it's runtime. As soon as the cell is run, the session will be ended and we will loose all the information. So. we will define an _InteractiveSession_ to keep the parameters for testing.\n",
    "\n",
    "To write all the summaries on _logs_ folder for Tensorboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training epoch: 1\n",
      "iter   0:\t Reconstruction loss=0.112\n",
      "iter 100:\t Reconstruction loss=0.039\n",
      "iter 200:\t Reconstruction loss=0.029\n",
      "iter 300:\t Reconstruction loss=0.028\n",
      "iter 400:\t Reconstruction loss=0.025\n",
      "iter 500:\t Reconstruction loss=0.025\n",
      "---------------------------------------------------------\n",
      "Epoch: 1, validation loss: 0.025\n",
      "---------------------------------------------------------\n",
      "Training epoch: 2\n",
      "iter   0:\t Reconstruction loss=0.024\n",
      "iter 100:\t Reconstruction loss=0.025\n",
      "iter 200:\t Reconstruction loss=0.024\n",
      "iter 300:\t Reconstruction loss=0.022\n",
      "iter 400:\t Reconstruction loss=0.023\n",
      "iter 500:\t Reconstruction loss=0.023\n",
      "---------------------------------------------------------\n",
      "Epoch: 2, validation loss: 0.023\n",
      "---------------------------------------------------------\n",
      "Training epoch: 3\n",
      "iter   0:\t Reconstruction loss=0.022\n",
      "iter 100:\t Reconstruction loss=0.023\n",
      "iter 200:\t Reconstruction loss=0.022\n",
      "iter 300:\t Reconstruction loss=0.022\n",
      "iter 400:\t Reconstruction loss=0.023\n",
      "iter 500:\t Reconstruction loss=0.022\n",
      "---------------------------------------------------------\n",
      "Epoch: 3, validation loss: 0.022\n",
      "---------------------------------------------------------\n",
      "Training epoch: 4\n",
      "iter   0:\t Reconstruction loss=0.023\n",
      "iter 100:\t Reconstruction loss=0.023\n",
      "iter 200:\t Reconstruction loss=0.022\n",
      "iter 300:\t Reconstruction loss=0.021\n",
      "iter 400:\t Reconstruction loss=0.022\n",
      "iter 500:\t Reconstruction loss=0.022\n",
      "---------------------------------------------------------\n",
      "Epoch: 4, validation loss: 0.022\n",
      "---------------------------------------------------------\n",
      "Training epoch: 5\n",
      "iter   0:\t Reconstruction loss=0.022\n",
      "iter 100:\t Reconstruction loss=0.024\n",
      "iter 200:\t Reconstruction loss=0.023\n",
      "iter 300:\t Reconstruction loss=0.022\n",
      "iter 400:\t Reconstruction loss=0.020\n",
      "iter 500:\t Reconstruction loss=0.021\n",
      "---------------------------------------------------------\n",
      "Epoch: 5, validation loss: 0.022\n",
      "---------------------------------------------------------\n",
      "Training epoch: 6\n",
      "iter   0:\t Reconstruction loss=0.022\n",
      "iter 100:\t Reconstruction loss=0.021\n",
      "iter 200:\t Reconstruction loss=0.021\n",
      "iter 300:\t Reconstruction loss=0.021\n",
      "iter 400:\t Reconstruction loss=0.022\n",
      "iter 500:\t Reconstruction loss=0.022\n",
      "---------------------------------------------------------\n",
      "Epoch: 6, validation loss: 0.022\n",
      "---------------------------------------------------------\n",
      "Training epoch: 7\n",
      "iter   0:\t Reconstruction loss=0.022\n",
      "iter 100:\t Reconstruction loss=0.021\n",
      "iter 200:\t Reconstruction loss=0.022\n",
      "iter 300:\t Reconstruction loss=0.020\n",
      "iter 400:\t Reconstruction loss=0.020\n",
      "iter 500:\t Reconstruction loss=0.021\n",
      "---------------------------------------------------------\n",
      "Epoch: 7, validation loss: 0.021\n",
      "---------------------------------------------------------\n",
      "Training epoch: 8\n",
      "iter   0:\t Reconstruction loss=0.021\n",
      "iter 100:\t Reconstruction loss=0.021\n",
      "iter 200:\t Reconstruction loss=0.021\n",
      "iter 300:\t Reconstruction loss=0.021\n",
      "iter 400:\t Reconstruction loss=0.021\n",
      "iter 500:\t Reconstruction loss=0.021\n",
      "---------------------------------------------------------\n",
      "Epoch: 8, validation loss: 0.021\n",
      "---------------------------------------------------------\n",
      "Training epoch: 9\n",
      "iter   0:\t Reconstruction loss=0.021\n",
      "iter 100:\t Reconstruction loss=0.021\n",
      "iter 200:\t Reconstruction loss=0.020\n",
      "iter 300:\t Reconstruction loss=0.022\n",
      "iter 400:\t Reconstruction loss=0.020\n",
      "iter 500:\t Reconstruction loss=0.021\n",
      "---------------------------------------------------------\n",
      "Epoch: 9, validation loss: 0.021\n",
      "---------------------------------------------------------\n",
      "Training epoch: 10\n",
      "iter   0:\t Reconstruction loss=0.021\n",
      "iter 100:\t Reconstruction loss=0.020\n",
      "iter 200:\t Reconstruction loss=0.021\n",
      "iter 300:\t Reconstruction loss=0.020\n",
      "iter 400:\t Reconstruction loss=0.021\n",
      "iter 500:\t Reconstruction loss=0.022\n",
      "---------------------------------------------------------\n",
      "Epoch: 10, validation loss: 0.021\n",
      "---------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Launch the graph (session)\n",
    "sess = tf.InteractiveSession() # using InteractiveSession instead of Session to test network in separate cell\n",
    "sess.run(init)\n",
    "train_writer = tf.summary.FileWriter(logs_path, sess.graph)\n",
    "num_tr_iter = int(mnist.train.num_examples / batch_size)\n",
    "global_step = 0\n",
    "for epoch in range(epochs):\n",
    "    print('Training epoch: {}'.format(epoch + 1))\n",
    "    for iteration in range(num_tr_iter):\n",
    "        batch_x, _ = mnist.train.next_batch(batch_size)\n",
    "        batch_x_noisy = batch_x + noise_level * np.random.normal(loc=0.0, scale=1.0, size=batch_x.shape)\n",
    "\n",
    "        global_step += 1\n",
    "        # Run optimization op (backprop)\n",
    "        feed_dict_batch = {x_original: batch_x, x_noisy: batch_x_noisy}\n",
    "        _, summary_tr = sess.run([optimizer, merged], feed_dict=feed_dict_batch)\n",
    "        train_writer.add_summary(summary_tr, global_step)\n",
    "\n",
    "        if iteration % display_freq == 0:\n",
    "            # Calculate and display the batch loss and accuracy\n",
    "            loss_batch = sess.run(loss,\n",
    "                                  feed_dict=feed_dict_batch)\n",
    "            print(\"iter {0:3d}:\\t Reconstruction loss={1:.3f}\".\n",
    "                  format(iteration, loss_batch))\n",
    "\n",
    "    # Run validation after every epoch\n",
    "    x_valid_original  = mnist.validation.images\n",
    "    x_valid_noisy = x_valid_original + noise_level * np.random.normal(loc=0.0, scale=1.0, size=x_valid_original.shape)\n",
    "\n",
    "\n",
    "    feed_dict_valid = {x_original: x_valid_original, x_noisy: x_valid_noisy}\n",
    "    loss_valid = sess.run(loss, feed_dict=feed_dict_valid)\n",
    "    print('---------------------------------------------------------')\n",
    "    print(\"Epoch: {0}, validation loss: {1:.3f}\".\n",
    "          format(epoch + 1, loss_valid))\n",
    "    print('---------------------------------------------------------')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test:\n",
    "Now that the model is trained. It is time to test our model.\n",
    "\n",
    "We will define some helper functions to plot the  original input data. Then we will add some noises to our image and we will feed the noisy image to the network and visualize the reconstructed image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_images(original_images, noisy_images, reconstructed_images):\n",
    "    \"\"\"\n",
    "    Create figure of original and reconstructed image.\n",
    "    :param original_image: original images to be plotted, (?, img_h*img_w)\n",
    "    :param noisy_image: original images to be plotted, (?, img_h*img_w)\n",
    "    :param reconstructed_image: reconstructed images to be plotted, (?, img_h*img_w)\n",
    "    \"\"\"\n",
    "    num_images = original_images.shape[0]\n",
    "    fig, axes = plt.subplots(num_images, 3, figsize=(9, 9))\n",
    "    fig.subplots_adjust(hspace=.1, wspace=0)\n",
    "    \n",
    "    img_h = img_w = np.sqrt(original_images.shape[-1]).astype(int)\n",
    "    for i, ax in enumerate(axes):\n",
    "        # Plot image.\n",
    "        ax[0].imshow(original_images[i].reshape((img_h, img_w)), cmap='gray')\n",
    "        ax[1].imshow(noisy_images[i].reshape((img_h, img_w)), cmap='gray')\n",
    "        ax[2].imshow(reconstructed_images[i].reshape((img_h, img_w)), cmap='gray')\n",
    "\n",
    "        # Remove ticks from the plot.\n",
    "        for sub_ax in ax:\n",
    "            sub_ax.set_xticks([])\n",
    "            sub_ax.set_yticks([])\n",
    "    \n",
    "    for ax, col in zip(axes[0], [\"Original Image\", \"Noisy Image\", \"Reconstructed Image\"]):\n",
    "        ax.set_title(col)\n",
    "    \n",
    "    fig.tight_layout()\n",
    "    plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---------------------------------------------------------\n",
      "Test loss of original image compared to reconstructed image : 0.018\n",
      "---------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "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pUqViuwzos+P/t60v1f1s+pR0GdN6xfos62+BOsbatOmjZvT2giKrjlFfQnWw6CehA0bNjht+6+EEMKsWbOc1t4S6p9I84yoh8F+du/eveHYsWPFXge8YQAAAIAobBgAAAAgChsGAAAAiFJh6zC8//77Tqfl+GaL9jDX2vXNmjVLxi1atHBzGpPS2BxUfAoLC8PTTz+d6Ntuu83Nb9682Wn7jKiHQZ+fnTt3Oq29JXr06OH00qVLnT7nnHOSscZ51e9gY68hZOara7659mywa27BggWpP6vn0volGjfW2G29evWSsa4p7WNh+3xoHjuULGn9IdLi7THvXKymQI0aNZzu2LGj0717907G6sXR69Lf91qHQZ9d7YNij6d/K5Tq1aunXouif9fUy5H22VzUIOENAwAAAERhwwAAAABR2DAAAABAlArjYdBa8xdffLHTNl6TbezGxqNDCOHDDz90et++fU4PHDgwGY8dOzb12D/96U+dHj9+fFbXBuWPr7/+2tVDUM+CegcaNGiQjK+44go3p8+WxuM153vKlClOa0659Thov4aGDRs6bb04IYTw5ptvOq31JNRvYe+B+iM0nqr9WBYvXuy09R2EkNlLwn5PrdGg8ex+/folY1uTAUoe60VQX0Kaf0ufj1gsv1atWk6rt0f/Ptg+Kfv373dz6vuxfWFCCGHVqlVOq29A+1bYa9NnUa9b+7d07drVaa3Dotdu75veb/27l02fj1OFNwwAAAAQhQ0DAAAARCm3IYnmzZs7/corrzht06xiaPlmfVX7yCOPOK3ld9OON2bMGDen6WRPPPGE0+eee67TTz31lNOl0aIUisd5550Xhg0bluimTZu6+TfeeMNp+1pS0/w0VVFTuLRksj5fo0aNcvrjjz9Oxhr+yM/Pd1rTKDUlWF+fDho0yOnt27cnY31utc2vDcuEkNnWu7CwMPXa7GthXUMalrH3X9tsQ8liX3sXJ41Pf1bLf2vISsuBq7brRssxT5gwwWl97jWtUsMMmqZpn239u6XPvYYB9dga/lixYoXTtnR0LI2VtEoAAAAoE9gwAAAAQBQ2DAAAABCl3HoYNIaVjWdh6tSpTt98881Oa/ndbLEeht///vdubty4cU5Xq1bNafU0vP32205rOhmUP44dO+Zi7pp+OHr0aKdt3PKdd95xc1qW1pa0DSEzfVjb52r8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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1d1d81d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Test the network after training\n",
    "# Make a noisy image\n",
    "test_samples = 5\n",
    "x_test = mnist.test.images[:test_samples]\n",
    "x_test_noisy = x_test + noise_level * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape)\n",
    "# Reconstruct a clean image from noisy image\n",
    "x_reconstruct = sess.run(out, feed_dict={x_noisy: x_test_noisy})\n",
    "# Calculate the loss between reconstructed image and original image\n",
    "loss_test = sess.run(loss, feed_dict={x_original: x_test, x_noisy: x_test_noisy})\n",
    "print('---------------------------------------------------------')\n",
    "print(\"Test loss of original image compared to reconstructed image : {0:.3f}\".format(loss_test))\n",
    "print('---------------------------------------------------------')\n",
    "\n",
    "# Plot original image, noisy image and reconstructed image\n",
    "plot_images(x_test, x_test_noisy, x_reconstruct)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After we are finished the testing, we will close the session to free the memory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# close the session after you are done with testing\n",
    "sess.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At this step our coding is done. We can inspect more in our network using the __Tensorboard__ open your terminal and type:\n",
    "```bash\n",
    "tensorboard --logdir=logs/noiseRemoval --host localhost\n",
    "```\n",
    "__NOTE:__ Don't forget to activate your environment !!!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Open the generated link in your browser."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Thanks for reading! If you have any question or doubt, feel free to leave a comment in our [website](http://easy-tensorflow.com/)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
